// MQTT连接管理模块
class MQTTManager {
    constructor() {
        this.client = null;
        this.isConnected = false;
        this.config = null;
        this.init();
    }

    init() {
        // 加载配置
        this.loadConfig();
    }

    loadConfig() {
        const savedConfig = localStorage.getItem('mqtt_control_panel_config');
        if (savedConfig) {
            try {
                this.config = JSON.parse(savedConfig);
            } catch (e) {
                console.error('配置加载失败:', e);
                this.config = null;
            }
        }
    }

    async connect() {
        if (!this.config || !this.config.mqtt) {
            throw new Error('请先配置MQTT连接参数');
        }

        const { brokerUrl, username, password, clientId, keepalive, clean, reconnectPeriod, connectTimeout } = this.config.mqtt;

        if (!brokerUrl) {
            throw new Error('MQTT Broker地址未配置');
        }

        try {
            // 确保MQTT.js已加载
            await this.loadMQTT();

            // 基于EMQX最佳实践的连接选项
            const options = {
                clientId: clientId || 'mqtt_web_' + Math.random().toString(16).substr(2, 8),
                clean: clean !== undefined ? clean : true,
                connectTimeout: connectTimeout || 4000,
                reconnectPeriod: reconnectPeriod || 1000,
                keepalive: keepalive || 60,
                protocolVersion: 4, // MQTT v3.1.1
                resubscribe: true    // 重连后自动重新订阅
            };

            // 处理认证信息
            if (username) {
                options.username = username;
                if (password) {
                    options.password = password;
                }
            }

            // 处理TLS/SSL连接的安全选项
            if (brokerUrl.startsWith('mqtts://') || brokerUrl.startsWith('wss://')) {
                options.rejectUnauthorized = false; // 允许自签名证书
            }

            this.client = mqtt.connect(brokerUrl, options);

            return new Promise((resolve, reject) => {
                const timeout = setTimeout(() => {
                    if (this.client) {
                        this.client.end(true); // 强制断开连接
                    }
                    reject(new Error('connack timeout'));
                }, (connectTimeout || 4000) + 2000); // 连接超时 + 缓冲时间

                this.client.on('connect', (packet) => {
                    clearTimeout(timeout);
                    this.isConnected = true;
                    this.updateUIStatus(true);
                    this.addLog(`MQTT连接成功 (Client ID: ${options.clientId})`);
                    resolve();
                });

                this.client.on('error', (error) => {
                    clearTimeout(timeout);
                    this.isConnected = false;
                    this.updateUIStatus(false);
                    
                    // 更详细的错误信息
                    const errorMsg = this.getConnectErrorMessage(error, brokerUrl);
                    this.addLog(`连接失败: ${errorMsg}`);
                    
                    if (this.client) {
                        this.client.end(true);
                    }
                    reject(new Error(errorMsg));
                });

                this.client.on('close', () => {
                    clearTimeout(timeout);
                    this.isConnected = false;
                    this.updateUIStatus(false);
                    this.addLog('MQTT连接已断开');
                });

                this.client.on('reconnect', () => {
                    this.addLog('正在重新连接...');
                });

                this.client.on('offline', () => {
                    this.addLog('MQTT连接离线');
                });

                this.client.on('message', (topic, message) => {
                    this.addLog(`收到消息 [${topic}]: ${message.toString()}`);
                });
            });

        } catch (error) {
            throw error;
        }
    }

    disconnect() {
        if (this.client) {
            this.client.end();
            this.client = null;
            this.isConnected = false;
            this.updateUIStatus(false);
            this.addLog('已断开MQTT连接');
        }
    }

    async publish(topic, payload, qos = 0, retain = false) {
        if (!this.isConnected || !this.client) {
            throw new Error('MQTT未连接');
        }

        // 验证QoS级别
        if (qos < 0 || qos > 2) {
            throw new Error('QoS级别必须为0、1或2');
        }

        return new Promise((resolve, reject) => {
            const options = {
                qos: qos,
                retain: retain
            };

            this.client.publish(topic, payload, options, (error) => {
                if (error) {
                    const errorMsg = this.getPublishErrorMessage(error, topic);
                    this.addLog(`发送失败 [${topic}]: ${errorMsg}`);
                    reject(error);
                } else {
                    const qosInfo = qos > 0 ? ` (QoS ${qos})` : '';
                    this.addLog(`发送成功 [${topic}]${qosInfo}: ${payload}`);
                    resolve();
                }
            });
        });
    }

    // 获取连接错误信息
    getConnectErrorMessage(error, brokerUrl) {
        const errorMsg = error.message || error.toString();
        
        // 常见MQTT连接错误诊断
        if (errorMsg.includes('connack timeout') || errorMsg.includes('连接超时')) {
            return `连接超时，请检查：
1. Broker地址是否正确: ${brokerUrl}
2. 网络连接是否正常
3. 防火墙设置`;
        } else if (errorMsg.includes('ECONNREFUSED')) {
            return `连接被拒绝，请检查：
1. Broker服务是否运行
2. 端口是否正确
3. 认证信息是否正确`;
        } else if (errorMsg.includes('ENOTFOUND')) {
            return `无法解析主机名，请检查Broker地址: ${brokerUrl}`;
        } else if (errorMsg.includes('UNAUTHORIZED')) {
            return '认证失败，请检查用户名和密码';
        } else if (errorMsg.includes('TLS') || errorMsg.includes('SSL')) {
            return 'TLS/SSL握手失败，请检查证书配置';
        } else if (errorMsg.includes('WebSocket')) {
            return 'WebSocket连接失败，请检查Broker是否支持WebSocket';
        } else if (errorMsg.includes('Invalid protocol')) {
            return `协议格式错误，请使用正确的协议前缀: mqtt://, mqtts://, ws://, wss://`;
        }
        
        return errorMsg;
    }

    // 获取发布错误信息
    getPublishErrorMessage(error, topic) {
        const errorMsg = error.message || error.toString();
        
        if (errorMsg.includes('Not connected')) {
            return 'MQTT连接已断开';
        } else if (errorMsg.includes('Invalid topic')) {
            return `主题格式无效: ${topic}`;
        } else if (errorMsg.includes('Message too long')) {
            return '消息长度超过限制';
        }
        
        return errorMsg;
    }

    // 测试连接功能
    async testConnection() {
        if (!this.config || !this.config.mqtt) {
            throw new Error('请先配置MQTT连接参数');
        }

        const { brokerUrl, username, password } = this.config.mqtt;

        if (!brokerUrl) {
            throw new Error('MQTT Broker地址未配置');
        }

        try {
            // 确保MQTT.js已加载
            await this.loadMQTT();
            
            // 使用测试专用的连接选项
            const testOptions = {
                clientId: 'test_client_' + Math.random().toString(16).substr(2, 8),
                clean: true,
                connectTimeout: 8000, // 更长的测试超时
                keepalive: 30,
                reconnectPeriod: 0, // 测试时不重连
                protocolVersion: 4
            };

            if (username) {
                testOptions.username = username;
                if (password) {
                    testOptions.password = password;
                }
            }

            if (brokerUrl.startsWith('mqtts://') || brokerUrl.startsWith('wss://')) {
                testOptions.rejectUnauthorized = false;
            }

            this.addLog(`开始测试连接: ${brokerUrl}`);
            
            const client = mqtt.connect(brokerUrl, testOptions);

            return new Promise((resolve) => {
                const timeout = setTimeout(() => {
                    client.end(true);
                    this.addLog('测试连接超时');
                    resolve(false);
                }, 10000);

                client.on('connect', () => {
                    clearTimeout(timeout);
                    this.addLog('✓ 连接测试成功');
                    client.end();
                    resolve(true);
                });

                client.on('error', (error) => {
                    clearTimeout(timeout);
                    const errorMsg = this.getConnectErrorMessage(error, brokerUrl);
                    this.addLog(`✗ 连接测试失败: ${errorMsg}`);
                    client.end();
                    resolve(false);
                });
            });

        } catch (error) {
            this.addLog(`测试连接异常: ${error.message}`);
            return false;
        }
    }

    async loadMQTT() {
        return new Promise((resolve, reject) => {
            if (typeof mqtt !== 'undefined') {
                console.log('MQTT.js已加载');
                resolve();
                return;
            }

            console.log('开始加载MQTT.js...');
            const script = document.createElement('script');
            script.src = 'https://unpkg.com/mqtt@4.3.7/dist/mqtt.min.js';
            
            script.onload = () => {
                console.log('MQTT.js加载成功');
                // 检查mqtt对象是否可用
                if (typeof mqtt === 'undefined') {
                    reject(new Error('MQTT.js加载但未定义'));
                    return;
                }
                resolve();
            };
            
            script.onerror = (error) => {
                console.error('MQTT.js加载失败:', error);
                reject(new Error('MQTT.js加载失败，请检查网络连接'));
            };
            
            document.head.appendChild(script);
        });
    }

    updateUIStatus(connected) {
        const statusElement = document.getElementById('mqtt-status');
        const connectBtn = document.getElementById('connect-btn');
        const disconnectBtn = document.getElementById('disconnect-btn');

        if (statusElement) {
            const dot = statusElement.querySelector('.status-dot');
            const text = statusElement.querySelector('.status-text');
            
            if (dot) {
                dot.className = connected ? 'status-dot connected' : 'status-dot';
            }
            if (text) {
                text.textContent = connected ? '已连接' : '未连接';
            }
        }

        if (connectBtn) {
            connectBtn.style.display = connected ? 'none' : 'inline-block';
        }
        if (disconnectBtn) {
            disconnectBtn.style.display = connected ? 'inline-block' : 'none';
        }

        // 更新控制按钮状态
        this.updateControlButtons(connected);
    }

    updateControlButtons(connected) {
        for (let i = 1; i <= 3; i++) {
            const btn = document.getElementById(`command-btn-${i}`);
            if (btn) {
                const config = this.config?.commands?.[i - 1];
                const hasConfig = config && config.topic && config.payload;
                
                btn.disabled = !connected || !hasConfig;
                
                const statusSpan = btn.querySelector('.btn-status');
                if (statusSpan) {
                    if (!hasConfig) {
                        statusSpan.textContent = '未配置';
                    } else if (!connected) {
                        statusSpan.textContent = '未连接';
                    } else {
                        statusSpan.textContent = '就绪';
                    }
                }
            }
        }
    }

    addLog(message) {
        const logContainer = document.getElementById('operation-log');
        if (!logContainer) return;

        const timestamp = new Date().toLocaleTimeString();
        const logEntry = document.createElement('div');
        logEntry.className = 'log-entry';
        logEntry.textContent = `[${timestamp}] ${message}`;

        logContainer.appendChild(logEntry);
        logContainer.scrollTop = logContainer.scrollHeight;

        // 限制日志条目数量
        const entries = logContainer.querySelectorAll('.log-entry');
        if (entries.length > 50) {
            entries[0].remove();
        }
    }

    clearLog() {
        const logContainer = document.getElementById('operation-log');
        if (logContainer) {
            logContainer.innerHTML = '<div class="log-entry">日志已清空</div>';
        }
    }

    getCommandConfig(index) {
        if (!this.config || !this.config.commands) {
            return null;
        }
        return this.config.commands[index - 1] || null;
    }

    isReady() {
        return this.isConnected && this.config && this.config.commands;
    }
}

// 全局MQTT管理器实例
window.mqttManager = new MQTTManager();